package control;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import remote.GestioneAbilitaRemote;
import util.LoginToken;

import com.oreilly.servlet.MultipartRequest;

import entity.Abilita;
import exception.AbilitaException;

public class GestioneAbilitaServlet extends Servlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		String to = (String) request.getParameter("to");
		if (to.equals("redirectToPaginaCreazioneAbilita"))
			this.redirectToPaginaCreazioneAbilita(request, response);
		if (to.equals("creaAbilita"))
			this.creaAbilita(request, response);
		if (to.equals("redirectToPaginaModificaAbilita"))
			this.redirectToPaginaModificaAbilita(request, response);
		if (to.equals("modificaAbilita"))
			this.modificaAbilita(request, response);
		if (to.equals("eliminaAbilita"))
			this.eliminaAbilita(request, response);
		if (to.equals("redirectToPaginaListaAbilitaAdmin"))
			this.redirectToPaginaListaAbilitaAdmin(request, response);
		if (to.equals("redirectToPaginaAbilitaDaValutare"))
			this.redirectToPaginaAbilitaDaValutare(request, response);
		if (to.equals("approvaAbilita"))
			this.approvaAbilita(request, response);
		if (to.equals("redirectToPaginaListaAbilitaUser"))
			this.redirectToPaginaListaAbilitaUser(request, response);
		if (to.equals("inserisciAbilitaUtente"))
			this.inserisciAbilitaUtente(request, response);
		if (to.equals("redirectToPaginaAggiungiAbilitaUtente"))
			this.redirectToPaginaAggiungiAbilitaUtente(request, response);
	}

	private void redirectToPaginaAbilitaDaValutare(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			List<Abilita> listaAbilitaDaApprovare = gestioneAbilitaRemote
					.getListaAbilitaDaApprovare();
			session.setAttribute("listaAbilitaDaApprovare",
					listaAbilitaDaApprovare);
			redirect("admin/abilitaDaValutare.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}

	}

	private void redirectToPaginaListaAbilitaUser(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");

			String username = tok.getUsername();

			session.removeAttribute("LoginToken");
			session.setAttribute("LoginToken", tok);

			List<Abilita> listaAbilita = gestioneAbilitaRemote
					.getListaAbilitaDiUtente(username);
			session.setAttribute("listaAbilita", listaAbilita);

			redirect("utente/listaAbilita.jsp", request, response);

		} catch (NamingException e) {
			e.printStackTrace();
		}

	}

	private void redirectToPaginaListaAbilitaAdmin(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			List<Abilita> listaAbilita = gestioneAbilitaRemote
					.getListaAbilita();

			session.setAttribute("listaAbilita", listaAbilita);

			redirect("admin/listaAbilitaAdmin.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}

	}

	
	private void redirectToPaginaCreazioneAbilita(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();

		LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
		String username = tok.getUsername();
		if (username.equals(Autenticazione.USERNAME_AMMINISTRATORE)) {
			redirect("admin/creaAbilitaAdmin.jsp", request, response);
		} else {
			redirect("utente/creaAbilita.jsp", request, response);

		}
	}

	private void modificaAbilita(HttpServletRequest request,
			HttpServletResponse response) {

		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			if (request.getParameter("idAbilita") == null)
				throw new AbilitaException(
						"Errore! Nessun'abilita' specificata");

			int idAbilita = Integer.parseInt(request.getParameter("idAbilita"));

			String nome = request.getParameter("nome");
			String descrizione = request.getParameter("descrizione");
			if (nome.length() == 0)
				throw new AbilitaException(
						"Non hai inserito il nome dell' abilita");
			if (descrizione.length() == 0)
				throw new AbilitaException(
						"Non hai inserito la descrizione dell' abilita");

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();
			if (username.equals(Autenticazione.USERNAME_AMMINISTRATORE)) {

				gestioneAbilitaRemote.modificaAbilita(idAbilita, nome,
						descrizione);
				session.setAttribute("Successo",
						"Abilita modificata correttamente");

				this.redirectToPaginaListaAbilitaAdmin(request, response);

			}

		} catch (AbilitaException e) {
			session.setAttribute("Errore", e.toString());
			redirect("admin/creaAbilitaAdmin.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

	private void approvaAbilita(HttpServletRequest request,
			HttpServletResponse response) {

		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			if (request.getParameter("idAbilita") == null)
				throw new AbilitaException(
						"Errore! Nessun'abilita' specificata");

			int idAbilita = Integer.parseInt(request.getParameter("idAbilita"));

			String stringIsApprovata = request.getParameter("isApprovata");

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();

			if (username.equals(Autenticazione.USERNAME_AMMINISTRATORE)) {
				if (stringIsApprovata.equals("true")) {
					gestioneAbilitaRemote.approvaAbilita(idAbilita);
					session.setAttribute("Successo",
							"Abilita approvata correttamente");
				} else {

					gestioneAbilitaRemote.eliminaAbilita(idAbilita);

					session.setAttribute("Successo",
							"Abilita rimossa correttamente");
				}

				this.redirectToPaginaAbilitaDaValutare(request, response);

			}

		} catch (NamingException e) {
			e.printStackTrace();
		} catch (AbilitaException e) {
			session.setAttribute("Errore", e.toString());
			redirect("admin/abilitaDaValutare.jsp", request, response);

		}
	}

	private void eliminaAbilita(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();

		try {

			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			if (request.getParameter("idAbilita") == null)
				throw new AbilitaException(
						"Errore! Nessun'abilita' specificata");

			int idAbilita = Integer.parseInt(request.getParameter("idAbilita"));

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();

			if (username.equals(Autenticazione.USERNAME_AMMINISTRATORE)) {
				gestioneAbilitaRemote.eliminaAbilita(idAbilita);
				session.setAttribute("Successo",
						"Abilita eliminata correttamente");
				this.redirectToPaginaListaAbilitaAdmin(request, response);

			} else {

				gestioneAbilitaRemote.eliminaAbilita(idAbilita);
				session.setAttribute("Successo",
						"Abilita creata correttamente, in fase di approvazione");

				redirect("utente/listaAbilita.jsp", request, response);

			}

		} catch (NamingException e) {
			e.printStackTrace();
		} catch (AbilitaException e) {
			session.setAttribute("Errore", e.toString());
			this.redirectToPaginaListaAbilitaAdmin(request, response);

		}
	}

	private void creaAbilita(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			String nome = request.getParameter("nome");
			String descrizione = request.getParameter("descrizione");

			if (nome.length() == 0)
				throw new AbilitaException(
						"Non hai inserito il nome dell' abilita");
			if (descrizione.length() == 0)
				throw new AbilitaException(
						"Non hai inserito la descrizione dell' abilita");

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();
			if (username.equals(Autenticazione.USERNAME_AMMINISTRATORE)) {
				gestioneAbilitaRemote.creaAbilita(nome, descrizione, true);
				session.setAttribute("Successo", "Abilita creata correttamente");

				this.redirectToPaginaListaAbilitaAdmin(request, response);

			} else {

				int idAbilita = gestioneAbilitaRemote.creaAbilita(nome,
						descrizione, false);

				gestioneAbilitaRemote.inserisciAbilitaInUtente(username,
						idAbilita);

				session.setAttribute("Successo",
						"Abilita creata correttamente, in fase di approvazione");

				this.redirectToPaginaListaAbilitaUser(request, response);
			}

		} catch (AbilitaException e) {
			session.setAttribute("Errore", e.toString());
			redirect("admin/creaAbilitaAdmin.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

	private void redirectToPaginaModificaAbilita(HttpServletRequest request,
			HttpServletResponse response) {

		try {
			HttpSession session = request.getSession();

			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			if (request.getParameter("idAbilita") == null)
				throw new AbilitaException(
						"Errore! Nessun'abilita' specificata");

			int idAbilita = Integer.parseInt(request.getParameter("idAbilita"));
			Abilita abilita = gestioneAbilitaRemote.getAbilita(idAbilita);
			session.setAttribute("abilita", abilita);

			redirect("admin/modificaAbilita.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		} catch (AbilitaException e) {
			redirect("admin/modificaAbilita.jsp", request, response);
			e.printStackTrace();
		}
	}

	private void inserisciAbilitaUtente(HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		HttpSession session = request.getSession();
		try {

			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);
			MultipartRequest multi = new MultipartRequest(request, "./");

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();

			List<Abilita> listaAbilitaUtente = gestioneAbilitaRemote
					.getListaAbilitaDiUtente(username);
			for (Abilita abilita : listaAbilitaUtente) {

				gestioneAbilitaRemote.eliminaAbilitaUtente(username,
						abilita.getIdAbilita());
			}

			if (multi.getParameterValues("idAbilita") != null) {
				String[] idSetAbility = multi.getParameterValues("idAbilita");
				int i;

				for (i = 0; i < idSetAbility.length; i++) {
					gestioneAbilitaRemote.inserisciAbilitaInUtente(username,
							Integer.parseInt(idSetAbility[i]));
				}
			}
			session.setAttribute("Successo",
					"Abilita' inserita/e correttamente.");

			this.redirectToPaginaListaAbilitaUser(request, response);

		} catch (NamingException e) {
			e.printStackTrace();
		}

	}

	private void redirectToPaginaAggiungiAbilitaUtente(
			HttpServletRequest request, HttpServletResponse response) {

		HttpSession session = request.getSession();
		try {

			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");

			String username = tok.getUsername();

			session.removeAttribute("LoginToken");
			session.setAttribute("LoginToken", tok);

			List<Abilita> listaAbilita = gestioneAbilitaRemote
					.getListaAbilita();

			List<Abilita> listaAbilitaUtente = gestioneAbilitaRemote
					.getListaAbilitaDiUtente(username);

			List<Abilita> listaAbilitaNONDiUtente = new ArrayList<Abilita>();
			if (listaAbilita != null) {
				for (Abilita abilita : listaAbilita) {
					boolean abilitaDiUtente = false;

					for (Abilita abilitaUtente : listaAbilitaUtente) {
						if (abilita.getIdAbilita() == abilitaUtente
								.getIdAbilita()) {
							abilitaDiUtente = true;
						}

					}
					if (!abilitaDiUtente) {
						listaAbilitaNONDiUtente.add(abilita);
					}
				}
			}

			session.setAttribute("listaAbilitaUtente", listaAbilitaUtente);
			session.setAttribute("listaAbilitaNONDiUtente",
					listaAbilitaNONDiUtente);

			redirect("utente/aggiungiAbilita.jsp", request, response);

		} catch (NamingException e) {
			e.printStackTrace();
		}

	}

}
